<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Http\Requests\Auth\SmsLoginRequest;
use App\Models\User;
use App\Models\UserBinds;
use App\Http\Traits\Auth\LoginTrait;
use App\Http\Traits\Auth\SocialiteTrait;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Request;
use Laravel\Socialite\Two\InvalidStateException;

class LoginController extends Controller
{
    use LoginTrait, SocialiteTrait;

    /**
     * 显示登录页面或跳转到第三方登录
     *
     * @param null $socialite
     *
     * @return \Illuminate\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function showLogin($socialite = null)
    {
        if ($socialite) {

            $this->forgetSocialite();

            // 使用第三方登录
            return $this->socialite($socialite)->redirect();
        }

        // 显示登录页面
        return $this->view('auth.login', [
            'socialite' => $this->getSocialite()
        ]);
    }


    /**
     * 使用账户密码登录
     *
     * @param LoginRequest $request
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     * @throws \Illuminate\Validation\ValidationException
     */
    public function login(LoginRequest $request)
    {
        $this->loginWithCredentials($request);

        return $this->intended();
    }

    /**
     * 显示短信登录页面
     *
     * @return \Illuminate\View\View
     */
    public function showSmsLogin()
    {
        return $this->view('auth.login-sms');
    }

    /**
     * 使用短信验证码登录
     *
     * @param SmsLoginRequest $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function smsLogin(SmsLoginRequest $request)
    {
        $this->loginWithSms($request);

        // 登录后跳转
        return $this->intended();
    }

    /**
     * 第三方登录回调
     *
     * @param Request $request
     * @param string $type
     *
     * @throws HttpResponseException
     * @return \Illuminate\Http\RedirectResponse
     */
    public function callback(Request $request, $type)
    {

        try {

            if (!$this->hasSocialite()) {

                // 获取第三方用户信息
                $socialite = $this->socialite($type)->user();

                $this->storeSocialite($type, $socialite);
            }

        } catch (InvalidStateException $exception) {

            $this->responseSocialiteExpired();
        }

        $socialite = $this->getSocialiteOrFail();

        if (!$this->check()) {
            // 未登录本地账号
            // 检查是否已经绑定账号
            if ($bind = UserBinds::with('user')->where([
                'type' => $type,
                'open_id' => $socialite->getId()
            ])->first()) {

                $this->guard()->login($bind->user);

                // 登录成功
                return $this->intended();
            }

            return $this->intended(route('auth.login'));

        }

        // 已登录用户
        $user = $this->user();


        if (!$userId = UserBinds::where([
            'type' => $type,
            'user_type' => get_class($user),
            'open_id' => $socialite->getId()
        ])->value('user_id')) {

            // 已登录本地账号, 与本地账号绑定
            $user->binds()->create($this->getSocialiteData());

        } elseif ($userId !== $this->user()->getKey()) {

            // 已被其他账号绑定
            return redirect()
                ->route('profile.binds')
                ->withError('该账号已经被其他账号绑定, 请解除后重试!');
        }

        // 更新
        $user->binds()->where([
            'type' => $type,
            'open_id' => $socialite->getId()
        ])->update($this->getSocialiteData());

        return $this->route('center.binds')
            ->withSuccess('账号绑定成功!');
    }

    /**
     * 登录完成
     *
     * @param Request $request
     * @param User $user
     */
    protected function authenticated(Request $request, User $user)
    {

        // 存在第三方登录账号
        if ($this->hasSocialite()) {

            // 清除第三方账号登录状态
            $this->forgetSocialite();
        }
    }

}
